package com.luoqiz.security.config.web;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

@Configuration
public class JsonHttpMessageConverConfiguration {

	@Primary
	@Bean
	@ConditionalOnProperty(name = { "spring.http.converters.preferred-json-mapper" }, havingValue = "fastJson")
	@ConditionalOnMissingBean({ FastJsonHttpMessageConverter.class }) // 3
	public HttpMessageConverter<?> fastJsonHttpMessageConverter() {
		// 1、需要先定义一个 convert 转换消息的对象;
		FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
		List<MediaType> supportedMediaTypes = new ArrayList<>();
		supportedMediaTypes.add(MediaType.APPLICATION_JSON);
		supportedMediaTypes.add(MediaType.APPLICATION_JSON_UTF8);
		supportedMediaTypes.add(MediaType.APPLICATION_ATOM_XML);
		supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);
		supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);
		supportedMediaTypes.add(MediaType.APPLICATION_PDF);
		supportedMediaTypes.add(MediaType.APPLICATION_RSS_XML);
		supportedMediaTypes.add(MediaType.APPLICATION_XHTML_XML);
		supportedMediaTypes.add(MediaType.APPLICATION_XML);
		supportedMediaTypes.add(MediaType.IMAGE_GIF);
		supportedMediaTypes.add(MediaType.IMAGE_JPEG);
		supportedMediaTypes.add(MediaType.IMAGE_PNG);
		supportedMediaTypes.add(MediaType.TEXT_EVENT_STREAM);
		supportedMediaTypes.add(MediaType.TEXT_HTML);
		supportedMediaTypes.add(MediaType.TEXT_MARKDOWN);
		supportedMediaTypes.add(MediaType.TEXT_PLAIN);
		supportedMediaTypes.add(MediaType.TEXT_XML);
		supportedMediaTypes.add(MediaType.ALL);
		fastConverter.setSupportedMediaTypes(supportedMediaTypes);
		// 2、添加fastJson 的配置信息，比如：是否要格式化返回的json数据;
		FastJsonConfigExt fastJsonConfig = new FastJsonConfigExt();
		// 修改配置返回内容的过滤
		// WriteNullListAsEmpty ：List字段如果为null,输出为[],而非null
		// WriteNullStringAsEmpty ： 字符类型字段如果为null,输出为"",而非null
		// DisableCircularReferenceDetect ：消除对同一对象循环引用的问题，默认为false（如果不配置有可能会进入死循环）
		// WriteNullBooleanAsFalse：Boolean字段如果为null,输出为false,而非null
		// WriteMapNullValue：是否输出值为null的字段,默认为false
		fastJsonConfig.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect,
				SerializerFeature.PrettyFormat, SerializerFeature.BrowserCompatible,
				SerializerFeature.WriteMapNullValue);

		// 设置null字段为字符串
//		ValueFilter valueFilter = new ValueFilter() {// 5
//			// o 是class
//			// s 是key值
//			// o1 是value值
//			public Object process(Object o, String s, Object o1) {
//				if (null == o1) {
//					o1 = "";
//				}
//				return o1;
//			}
//		};
//设置数据过滤
		// fastJsonConfig.setSerializeFilters(valueFilter);

		//此处添加过滤器
//		int length = fastJsonConfig.getSerializeFilters().length;
//		SerializeFilter[] filters = new SerializeFilter[length + 1];
//		System.arraycopy(fastJsonConfig.getSerializeFilters(), 0, filters, 0, length);
//		filters[filters.length - 1] = new OAuth2AccessTokenFilter();
//		fastJsonConfig.setSerializeFilters(filters);
		// 3、在convert中添加配置信息.
		fastConverter.setFastJsonConfig(fastJsonConfig);
		return fastConverter;
	}

	@Primary
	@Bean
	@ConditionalOnProperty(name = {
			"spring.http.converters.preferred-json-mapper" }, havingValue = "jackson", matchIfMissing = true)
	public HttpMessageConverter<?> Jackson2HttpMessageConverter() {
		MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
		ObjectMapper objectMapper = new ObjectMapper();
		/**
		 * 序列换成json时,将所有的long变成string 因为js中得数字类型不能包含所有的java long值
		 */
		SimpleModule simpleModule = new SimpleModule();
		simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
		simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
		simpleModule.addSerializer(BigInteger.class, ToStringSerializer.instance);
		objectMapper.registerModule(simpleModule);
		jackson2HttpMessageConverter.setObjectMapper(objectMapper);
		return jackson2HttpMessageConverter;
	}
}
